package net.truthcontrol.openid4wicket;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import net.truthcontrol.openid4wicket.OpenIdService.AttributeRequest;

import org.apache.wicket.AttributeModifier;
import org.apache.wicket.MetaDataKey;
import org.apache.wicket.behavior.AttributeAppender;
import org.apache.wicket.markup.html.link.Link;
import org.apache.wicket.markup.html.list.ListItem;
import org.apache.wicket.markup.html.list.ListView;
import org.apache.wicket.markup.html.panel.Panel;
import org.apache.wicket.request.flow.RedirectToUrlException;
import org.apache.wicket.util.io.IClusterable;
import org.openid4java.discovery.DiscoveryInformation;
import org.openid4java.message.AuthRequest;

public class OpenIdPanel extends Panel {

	/**
	 * Key for putting the discovery information into the session.
	 */
	public static final MetaDataKey<DiscoveryInformation> DISCOVERY_INFORMATION_KEY = new MetaDataKey<DiscoveryInformation>() {
		private static final long serialVersionUID = 1L;
		};
		
	
	private class OpenIdButton extends Link<Void> {

		/** */
		private static final long serialVersionUID = 1L;
		private OpenIdItem item;

		public OpenIdButton(final String id, final OpenIdItem item) {
			super(id);
			this.item = item;
		}
		
		@Override
		protected void onInitialize() {
			super.onInitialize();
			
			if (settings.getCssClassButtons() != null) {
				add(new AttributeAppender("class", settings.getCssClassButtons()));
			}
			add(new AttributeModifier("src", "images/openid/" + item.getId() + ".png"));
		}
		
		@Override
		public void onClick() {
			
			DiscoveryInformation discoveryInformation =
					OpenIdService.performDiscoveryOnUserSuppliedIdentifier(item.getDiscoveryUrl());
			
			getSession().setMetaData(DISCOVERY_INFORMATION_KEY, discoveryInformation);
			
			AuthRequest authRequest =
					OpenIdService.createOpenIdAuthRequest(discoveryInformation, returnToUrl, attributes);
			
			// Now take the AuthRequest and forward it on to the OP
			throw new RedirectToUrlException(authRequest.getDestinationUrl(true));
			
		}
	}
	
	public static class AdvancedSettings implements IClusterable {
		
		/** */
		private static final long serialVersionUID = 1L;
		private final List<String> providers;
		/**
		 * CSS Class of the buttons.
		 */
		private final String cssClassButtons;
		private final String cssClass;
		
		private final String surroundingElement;
		private final String surroundingElementAttribute;
		
		public AdvancedSettings(final List<String> providers, final String cssClass, final String cssClassButtons, final String surroundingElement,
								final String surroundingElementAttribute) {
			super();
			this.providers = providers;
			this.cssClass = cssClass;
			this.cssClassButtons = cssClassButtons;
			this.surroundingElement = surroundingElement;
			this.surroundingElementAttribute = surroundingElementAttribute;
		}

		public List<String> getProviders() {
			return providers;
		}

		public String getCssClassButtons() {
			return cssClassButtons;
		}

		public String getSurroundingElement() {
			return surroundingElement;
		}

		public String getSurroundingElementAttribute() {
			return surroundingElementAttribute;
		}

		public String getCssClass() {
			return cssClass;
		}
		
	}
	
	public static class OpenIdItem implements IClusterable {
		/** */
		private static final long serialVersionUID = 1L;
		
		private String id;
		private String discoveryUrl;
		
		public OpenIdItem(String id, String discoveryUrl) {
			super();
			this.id = id;
			this.discoveryUrl = discoveryUrl;
		}

		public String getId() {
			return id;
		}

		public void setId(String id) {
			this.id = id;
		}

		public String getDiscoveryUrl() {
			return discoveryUrl;
		}

		public void setDiscoveryUrl(String discoveryUrl) {
			this.discoveryUrl = discoveryUrl;
		}
		
		
		
		
	}
	
	
	
	/** */
	private static final long serialVersionUID = 1L;
	
	/**
	 * Return to this URL after authentication.
	 */
	private final String returnToUrl;
	


	/**
	 * Try to retrieve these attributes.
	 */
	private final List<AttributeRequest> attributes;
	
	
	private static final List<OpenIdItem> discoveryUrls = new ArrayList<OpenIdPanel.OpenIdItem>();

	private final AdvancedSettings settings;
	
	// TODO set in properties file
	static {
		discoveryUrls.add(new OpenIdItem("google", "https://www.google.com/accounts/o8/id"));
		discoveryUrls.add(new OpenIdItem("yahoo", "https://me.yahoo.com/"));
		discoveryUrls.add(new OpenIdItem("myopenid", "https://myopenid.com/"));
		discoveryUrls.add(new OpenIdItem("aol", "https://openid.aol.com/"));
	}

	public OpenIdPanel(final String id, final String returnToUrl, final List<AttributeRequest> attributes, final AdvancedSettings settings) {
		super(id);
		this.returnToUrl = returnToUrl;
		this.attributes = attributes;
		this.settings = settings;
	}
	
	@Override
	protected void onInitialize() {
		super.onInitialize();
		
		ListView<OpenIdItem> listview = new ListView<OpenIdItem>("listview", discoveryUrls) {
			/** */
			private static final long serialVersionUID = 1L;

			@Override
			protected void populateItem(ListItem<OpenIdItem> item) {
				item.add(new OpenIdButton("openid_item",item.getModelObject()));
				item.add(new AttributeAppender("class", settings.getCssClass()));
			}
		};
		
		
		add(listview);
		
	}
	
}
